package com.linkoog.devtools.install_plugin_locally;

import com.intellij.ide.actions.RestartIdeAction;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.linkoog.devtools.utils.ExplorerHolder;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;

/**
 *   插件本地安装
 */
public class InstallPluginLocallyAction extends AnAction {

    private static final Logger LOG = Logger.getInstance(InstallPluginLocallyAction.class);

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        Project project = e.getData(CommonDataKeys.PROJECT);
        if (project == null) return;

        VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
        if (virtualFile == null || !virtualFile.isDirectory()) return;

        PluginDescriptor pluginDescriptor = PluginManager.getPluginByClass(OpenPluginFolderAction.class);
        if (pluginDescriptor == null) return;

        Path pluginPath = pluginDescriptor.getPluginPath();
        if (pluginPath == null) return;

        Path source = virtualFile.toNioPath();
        Path target = pluginPath.getParent();
        ProgressManager.getInstance().run(new Task.Backgroundable(project, "DevTools install plugin"){

            @Override
            public void run(@NotNull ProgressIndicator indicator) {
                try {
                    copyDirectory(source, target);
                }catch (Exception exception){
                    LOG.error("安装插件时，复制文件出错：", exception);
                }

                AnAction restartIdeAction = ActionManager.getInstance().getAction("RestartIde");
                restartIdeAction.actionPerformed(e);
            }
        });
    }

    private void copyDirectory(Path source, Path target) throws IOException {
        Files.walkFileTree(source, new SimpleFileVisitor<>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Path relativeSource = source.getParent().relativize(file); // 获取相对于源文件夹的路径
                Path destination = target.resolve(relativeSource); // 构建目标文件夹中的路径

                if (attrs.isDirectory()) {
                    Files.createDirectories(destination); // 如果当前访问的是文件夹，则创建该文件夹
                } else {
                    Files.copy(file, destination, StandardCopyOption.REPLACE_EXISTING); // 否则复制文件到目标位置
                }

                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                Path relativeSource = source.getParent().relativize(dir); // 获取相对于源文件夹的路径
                Path destination = target.resolve(relativeSource); // 构建目标文件夹中的路径

                try {
                    Files.createDirectories(destination); // 递归地创建所有必需的文件夹
                } catch (Exception e) {
                    System.out.println("无法创建文件夹 " + destination);
                }

                return super.preVisitDirectory(dir, attrs);
            }
        });
    }


    @Override
    public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
    }

    @Override
    public void update(@NotNull AnActionEvent e) {
        VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
        if (virtualFile == null) {
            e.getPresentation().setEnabled(false);
            return;
        }

        e.getPresentation().setEnabled(virtualFile.isDirectory());
    }


}
